package com.rykj.qxj.server.services.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rykj.qxj.server.dao.AuditManageMapper;
import com.rykj.qxj.server.dao.MetadataBasicMapper;
import com.rykj.qxj.server.dao.MetadataElementMapper;
import com.rykj.qxj.server.model.entity.AuditRecord;
import com.rykj.qxj.server.model.entity.MetadataBasic;
import com.rykj.qxj.server.model.entity.MetadataElement;
import com.rykj.qxj.server.model.param.AuditParams;
import com.rykj.qxj.server.model.param.AuditTableParams;
import com.rykj.qxj.server.services.IAuditManageService;
import com.rykj.qxj.server.services.IMetadataManageService;
import com.rykj.qxj.server.util.AuditConstant;
import com.rykj.qxj.server.util.object.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("auditManageService")
public class AuditManageServiceImpl implements IAuditManageService {
    @Autowired
    private AuditManageMapper auditManageMapper;
    @Autowired
    private IMetadataManageService metadataManageService;
    @Autowired
    private MetadataElementMapper metadataElementMapper;
    @Autowired
    private MetadataBasicMapper metadataBasicMapper;

    @Override
    public PageInfo getAuditRecordList(Integer pageNum, Integer pageSize, String applyName, Integer applyId, String tableName, String auditStatus, String changeType, Integer databaseId) {
        PageHelper.startPage(pageNum, pageSize);
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("applyName", applyName);
        paraMap.put("tableName", tableName);
        paraMap.put("auditStatus", auditStatus);
        paraMap.put("changeType", changeType);
        paraMap.put("applyId", applyId);
        paraMap.put("databaseId", databaseId);
        List<Map<String, Object>> audits = auditManageMapper.getAuditRecordList(paraMap);
        PageInfo pageInfo = new PageInfo(audits);
        return pageInfo;
    }

    @Override
    public Map<String, Object> getAuditRecordDetails(Integer auditId) {
        return auditManageMapper.getAuditRecordDetails(auditId);
    }

    @Override
    public String updateAuditOperation(AuditParams auditParams) throws Exception {
        String errorMsg = "";
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("auditId", auditParams.getAuditId());
        paraMap.put("auditStatus", auditParams.getAuditStatus());
        paraMap.put("auditor", auditParams.getAuditor());
        paraMap.put("auditRemark",auditParams.getAuditRemark());
        //审核通过
        if ("pass".equals(auditParams.getAuditStatus())) {
            paraMap.put("status", "normal");
            //2.新的申请生效操作,
            metadataElementMapper.saveByAuditId(paraMap);
            if(AuditConstant.CHANGETYPE_DELETETABLE.equals(auditParams.getChangeType())){
                metadataManageService.dropAuditTable(auditParams);
                metadataBasicMapper.deleteMetadataBasicById(auditParams.getTableId());
            }else
            if(AuditConstant.CHANGETYPE_CREATE.equals(auditParams.getChangeType())){
                errorMsg = metadataManageService.createdAuditTable(auditParams);
            }else
            // 审核通过，如果是修改操作，需要把原来的任务和规则，继承到新修改的字段上
            if (AuditConstant.CHANGETYPE_UPDATE.equals(auditParams.getChangeType())) {
                auditManageMapper.saveNewFieldRule(auditParams.getAuditId());
                auditManageMapper.saveNewFieldTask(auditParams.getAuditId());
                errorMsg = metadataManageService.modifyAuditFields(auditParams);
            } else if (AuditConstant.CHANGETYPE_INSERT.equals(auditParams.getChangeType())) {
                errorMsg = metadataManageService.addAuditFields(auditParams);
            } else {
                errorMsg = metadataManageService.dropAuditFields(auditParams);
            }
            //3.删除之前的字段
            metadataElementMapper.deleteByAuditId(paraMap);
        }
        if(StringUtils.isEmpty(errorMsg)){
            //1.审核状态修改
            auditManageMapper.updateAuditStatus(paraMap);
        }
        return errorMsg;
    }
    @Override
    public List<MetadataElement> getAuditFieldDetails(Integer auditId) {
        return metadataElementMapper.getAuditFieldDetails(auditId);
    }

    /**
     * @param auditRecord
     */
    @Override
    public String saveAuditRecord(AuditRecord auditRecord) throws Exception {

        List<MetadataElement> metadataElements = auditRecord.getMetadataElements();
        if (AuditConstant.CHANGETYPE_CREATE.equals(auditRecord.getChangeType())) {
            MetadataBasic metadataBasic = auditRecord.getMetadataBasic();

            String tableBuildStatement = metadataBasic.getTableBuildStatement();
            if (StringUtils.isNotEmpty(tableBuildStatement)) {
                metadataElements = metadataManageService.getElement(metadataBasic);
            }
            if (CollectionUtils.isEmpty(metadataElements)) {
                return "新建表必须至少有一个字段元素";
            }
            Integer metadataId = metadataManageService.checkTableName(metadataBasic.getTableName(), metadataBasic.getBelongDatabase());
            if (metadataId != null) {
                return "表名"+metadataBasic.getTableName()+"已存在";
            }
            String errorMsg = checkElementRepeat(metadataElements);
            if(StringUtils.isNotEmpty(errorMsg)){
               return errorMsg;
            }
            metadataBasicMapper.saveMetadataBasic(metadataBasic);
            auditRecord.setTableId(metadataBasic.getId());
            auditManageMapper.saveAuditRecord(auditRecord);
            if (!CollectionUtils.isEmpty(metadataElements)) {
                metadataElements.forEach(e -> {
                    e.setTableId(metadataBasic.getId());
                    e.setAuditId(auditRecord.getId());
                });
                metadataElementMapper.saveAuditMetadataElement(metadataElements);
            }
           return "";
        }
        String errorMsg = checkElementRepeat(metadataElements);
        if(StringUtils.isNotEmpty(errorMsg)){
            return errorMsg;
        }
        //保存申请信息
        auditManageMapper.saveAuditRecord(auditRecord);
        if (AuditConstant.CHANGETYPE_INSERT.equals(auditRecord.getChangeType())) {
            Map<String,Object> paraMap = new HashMap<>();
            for (MetadataElement element:  metadataElements) {
                paraMap.put("tableId",element.getTableId());
                paraMap.put("fieldName",element.getFieldName());
                if(("date".equals(element.getFieldType()) ||"datetime".equals(element.getFieldType()))&& element.getFieldLength()>0){
                    throw new Exception("日期类型不需要长度");
                }
                MetadataElement checkElement = metadataElementMapper.checkElement(paraMap);
                if(checkElement !=null ){
                    if(checkElement!=null){
                        //抛异常是为了 使事务生效
                        throw  new Exception("字段"+checkElement.getFieldName()+"已存在");
                    }
                }
                element.setAuditId(auditRecord.getId());
                element.setStatus("delete");
            }
            metadataElementMapper.saveAuditMetadataElement(metadataElements);
        }
        if (AuditConstant.CHANGETYPE_UPDATE.equals(auditRecord.getChangeType())) {
            List<Map<String, Object>> auditFields = new ArrayList<>();
            Map<String,Object> paraMap = new HashMap<>();
            for (MetadataElement element:metadataElements ) {
                paraMap.put("tableId",element.getTableId());
                paraMap.put("fieldName",element.getFieldName());
                if(("date".equals(element.getFieldType())||"datetime".equals(element.getFieldType())) && element.getFieldLength()>0){
                    throw new Exception("日期类型不需要长度");
                }
                MetadataElement checkElement = metadataElementMapper.checkElement(paraMap);
                if(checkElement !=null && checkElement.getId()!=element.getId()){
                    if(checkElement!=null){
                        throw  new Exception("字段"+checkElement.getFieldName()+"已存在");
                    }
                }
                element.setAuditId(auditRecord.getId());
                element.setStatus("delete");
                Map<String, Object> auditField = new HashMap<>();
                auditField.put("auditId", auditRecord.getId());
                auditField.put("fieldId", element.getId());
                auditFields.add(auditField);
            }
            metadataElementMapper.saveAuditMetadataElement(metadataElements);
            auditManageMapper.saveAuditField(auditFields);
        }
        if (AuditConstant.CHANGETYPE_DELETE.equals(auditRecord.getChangeType())) {
            List<Map<String, Object>> auditFields = new ArrayList<>();
            metadataElements.forEach(m -> {
                Map<String, Object> auditField = new HashMap<>();
                auditField.put("auditId", auditRecord.getId());
                auditField.put("fieldId", m.getId());
                auditFields.add(auditField);
            });
            auditManageMapper.saveAuditField(auditFields);
        }
        return "";
    }

    /**
     * 检测字段名是否重复
     * @param metadataElements
     * @return
     */
    private String checkElementRepeat(List<MetadataElement> metadataElements) {
        Map<String,Object> chekMap = new HashMap<>();
        for (MetadataElement element: metadataElements) {
            if (chekMap.containsKey(element.getFieldName().toLowerCase())){
                return "字段 "+element.getFieldName()+" 重复";
            }
            chekMap.put(element.getFieldName(),element.getFieldName());
        }
        return "";
    }
    @Override
    public void deleteTableAudit(AuditTableParams auditTableParams) {
        AuditRecord auditRecord = new AuditRecord();
        auditRecord.setApplyId(auditTableParams.getApplyId());
        auditRecord.setTableId(auditTableParams.getTableId());
        auditRecord.setChangeType(auditTableParams.getChangeType());
        auditRecord.setAuditStatus(auditTableParams.getAuditStatus());
        auditRecord.setCreatedBy(auditTableParams.getCreatedBy());
        auditRecord.setDatabaseId(auditTableParams.getDatabaseId());
        auditRecord.setVersionNum(auditTableParams.getVersionNum());
        auditRecord.setStatus(auditTableParams.getStatus());
        //保存申请信息
        auditManageMapper.saveAuditRecord(auditRecord);
    }
    @Override
    public List<MetadataElement> getDropAuditFieldDetails(Integer auditId) {
      return   metadataElementMapper.getDropAuditFieldDetails(auditId);
    }
    @Override
    public String updateAuditElements(List<MetadataElement> metadataElements) {
        String errorMsg = checkElementRepeat(metadataElements);
        if(StringUtils.isNotEmpty(errorMsg)){
            return errorMsg;
        }
        Map<String,Object> paraMap = new HashMap<>();

        if(!CollectionUtils.isEmpty(metadataElements)){
            List<MetadataElement> addElements = new ArrayList<>();
            for (MetadataElement e:metadataElements ) {
                paraMap.put("tableId",e.getTableId());
                paraMap.put("fieldName",e.getFieldName());
                MetadataElement checkElement = metadataElementMapper.checkElement(paraMap);
                if(checkElement!=null && checkElement.getId()!=e.getId()){
                    return "字段"+checkElement.getFieldName()+"已存在";
                }
                if(e.getId()>0){
                    metadataElementMapper.updateMetadataElement(e);
                }else {
                    addElements.add(e);
                }
            }
            if(!CollectionUtils.isEmpty(addElements)){
                metadataElementMapper.saveAuditMetadataElement(addElements);
            }
        }
        return "";
    }
    @Override
    public void updateAuditStatus(Integer auditId, String auditStatus) {
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("auditId",auditId);
        paraMap.put("auditStatus", auditStatus);
        auditManageMapper.updateAuditStatusById(paraMap);
    }
    @Override
    public String addAuditElements(List<MetadataElement> metadataElements) {
        String errorMsg = checkElementRepeat(metadataElements);
        if(StringUtils.isNotEmpty(errorMsg)){
            return errorMsg;
        }
        Map<String,Object> paraMap = new HashMap<>();
        for (MetadataElement element:metadataElements) {
            paraMap.put("tableId",element.getTableId());
            paraMap.put("fieldName",element.getFieldName());
            MetadataElement checkElement = metadataElementMapper.checkElement(paraMap);
            if(checkElement!=null){
                return "字段"+checkElement.getFieldName()+"已存在";
            }
        }
        if(!CollectionUtils.isEmpty(metadataElements)){
            metadataElementMapper.saveAuditMetadataElement(metadataElements);
        }
        return "";
    }
    @Override
    public void deleteAuditElement(Integer auditElementId) {
        metadataElementMapper.deleteAuditElement(auditElementId);
    }
}
